package com.example.pluto.user.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.pluto.common.utils.RandomInfo;
import com.example.pluto.user.entity.PlutoUser;
import com.example.pluto.user.mapper.PlutoUserMapper;
import com.example.pluto.user.mapper.PlutoUserRepository;
import com.example.pluto.user.service.PlutoUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author hzhb
 * @description 针对表【pluto_user】的数据库操作Service实现
 * @createDate 2024-12-12 16:37:21
 */
@Service
public class PlutoUserServiceImpl extends ServiceImpl<PlutoUserMapper, PlutoUser> implements PlutoUserService {
    private static final int BATCH_SIZE = 10000;
    private static final int THREAD_POOL_SIZE = Runtime.getRuntime().availableProcessors();

    @Autowired
    private PlutoUserMapper plutoUserMapper;

    public ExecutorService threadExecutor = new ThreadPoolExecutor(10, 1000000, 10L, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1), new ThreadPoolExecutor.AbortPolicy()
            //DiscardPolicy拒绝不会抛出异常
            //DiscardOldestPolicy尝试和最早的竞争， ，不会操出异常
            //AbortPolicy 拒绝抛出异常
            //CallerRunsPolicy 哪来的去哪儿 main线程
    );

    @Override
    public void savePlutoUser() {
        Date date = new Date();
        List<PlutoUser> list = new ArrayList<>();
        list.clear();
        for (int i = 0; i < 1000000; i++) {
            PlutoUser plutoUser = new PlutoUser();
            plutoUser.setCreateTime(date);
            plutoUser.setId(IdUtil.getSnowflakeNextId());
            //获取性别和name
            if (RandomInfo.randomInt(2) % 2 == 0) {
                plutoUser.setRealName(RandomInfo.getRandomBoyName());
            } else {
                plutoUser.setRealName(RandomInfo.getRandomBoyName());
            }
            //获取年龄
            plutoUser.setAge(RandomInfo.getRandomAge());
            //获取密码
            plutoUser.setPassword(RandomInfo.getRandomPassword());
            //获取邮箱
            plutoUser.setEmail(RandomInfo.getRandomQQEmail());
            //获取地址
            plutoUser.setAddress(RandomInfo.getRandomAddress());
            list.add(plutoUser);
        }
        this.remove(Wrappers.lambdaQuery());
        Date date2 = new Date();
        List<List<PlutoUser>> partitions = partition(list, BATCH_SIZE * THREAD_POOL_SIZE);
        for (int i = 0; i < partitions.size(); i++) {
            final List<PlutoUser> partition = partitions.get(i);
            threadExecutor.submit(() -> {
                this.saveBatch(partition);
            });
        }
        System.out.println("*************************开始时间：" + DateUtil.format(date, "yyyy-MM-dd HH:mm:ss.SSS"));
        System.out.println("*************************结束时间：" + DateUtil.format(date2, "yyyy-MM-dd HH:mm:ss.SSS"));
        long seconds = DateUtil.between(date, date2, DateUnit.SECOND);
        long ms = DateUtil.between(date, date2, DateUnit.MS);
        System.out.println("两个时间相差 " + seconds + " 秒");
        System.out.println("两个时间相差 " + ms + " 毫秒");
    }

    private List<List<PlutoUser>> partition(List<PlutoUser> list, int size) {
        return IntStream.range(0, (list.size() + size - 1) / size).mapToObj(i -> list.subList(i * size, Math.min((i + 1) * size, list.size()))).collect(Collectors.toList());
    }

    @Autowired
    private PlutoUserRepository plutoUserRepository;

    @Override
    public void saveEs() {
        getAllUsersInBatches(1);
    }

    public void getAllUsersInBatches(int currentPage) {

        Page<PlutoUser> page = new Page<>(currentPage, 10000);
        IPage<PlutoUser> pageResult = plutoUserMapper.selectPage(page, null);

        if (pageResult.getRecords().isEmpty()) {
            // 如果当前页没有数据，则停止查询
        } else {
            // 将当前页的数据添加到总列表中
            plutoUserRepository.saveAll(pageResult.getRecords());
            // 增加页码以便查询下一页
            currentPage++;
            getAllUsersInBatches(currentPage);


        }
    }

}




